package cn.xshi.file.web;

import cn.xshi.common.annotation.Auth;
import cn.xshi.common.base.BaseAction;
import cn.xshi.common.base.BaseJson;
import cn.xshi.common.base.BaseResult;
import cn.xshi.common.constant.PathConstant;
import cn.xshi.common.entity.AttachmentEntity;
import cn.xshi.common.entity.PathEntity;
import cn.xshi.common.entity.UploadEntity;
import cn.xshi.common.util.ExceptionUtil;
import cn.xshi.common.util.JsonUtil;
import cn.xshi.common.util.file.FileEntity;
import cn.xshi.common.util.file.FileUtil;
import cn.xshi.file.model.Attachment;
import cn.xshi.file.service.AttachmentService;
import cn.xshi.file.util.Constant;
import cn.xshi.file.util.FileService;
import cn.xshi.file.util.office.OfficeUtil;
import com.github.pagehelper.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * @Desc 通用API
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@RestController
@Api(value = "通用API",tags = "通用API",description = "通用API")
@Slf4j
public class FileController extends BaseAction {

    @Resource
    private AttachmentService attachmentService;

    @Resource
    private FileService fileService;

    @Resource
    private OfficeUtil officeUtil;

    /**
     * 单个上传
     * @param map 校验类型
     * @return
     */
    @PostMapping(value="/upload")
    @ApiOperation(value="上传文件", notes="上传文件")
    @Auth(value = "/upload",authenticationType = Auth.AuthorizationType.NOT_REQUIRED_LOGIN)
    public BaseResult<BaseJson> upload(@RequestParam Map<String, Object> map, @RequestParam("picFile") MultipartFile multipartFile){
        BaseJson baseJson = new BaseJson();
        List<MultipartFile> multipartFileList = new ArrayList<>();
        if(null != multipartFile){
            multipartFileList.add(multipartFile);
        }
        UploadEntity uploadEntity = JsonUtil.fromFastJson(map, UploadEntity.class);
        try {
            //默认绝对路径
            String path = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_DEFAULT_PATH).get(0).getPath();
            //相对路径
            String relativePath = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_DEFAULT_RELATIVE_PATH).get(0).getPath();
            //校验xt_path_absolutek
            if(!StringUtils.isEmpty(uploadEntity.getPathAbsolutek())){
                if(!StringUtils.isEmpty(baseUtils.getSysPathCache(uploadEntity.getPathAbsolutek()).get(0).getPath())){
                    path = baseUtils.getSysPathCache(uploadEntity.getPathAbsolutek()).get(0).getPath();
                }
            }
            //校验xt_path_relativek
            if(!StringUtils.isEmpty(uploadEntity.getPathRelativek())){
                if(!StringUtils.isEmpty(baseUtils.getSysPathCache(uploadEntity.getPathRelativek()).get(0).getPath())){
                    relativePath = baseUtils.getSysPathCache(uploadEntity.getPathRelativek()).get(0).getPath();
                }
            }
            FileUtil.initPath(path);
            uploadEntity.setPathRelativek(relativePath);
            List<Attachment> attachmentList = fileService.upLoad(uploadEntity,multipartFileList,path);
            int i = attachmentService.addAttachment(attachmentList.get(0));
            if(i>0){
                baseJson.setJsonID(attachmentList.get(0).getId());
                baseJson.setMessage("上传成功");
                baseJson.setObject(attachmentList.get(0));
                baseJson.setFileType(attachmentList.get(0).getType());
                if(null != attachmentList.get(0).getType() && !"".equals(attachmentList.get(0).getType())){
                    if("image/jpeg".equals(attachmentList.get(0).getType())||
                            "image/png".equals(attachmentList.get(0).getType())||
                            "image/gif".equals(attachmentList.get(0).getType())||
                            "image/bmp".equals(attachmentList.get(0).getType())){
                        //校验是否为自定义路径
                        if(!StringUtils.isEmpty(uploadEntity.getPathUrlk())){
                            baseJson.setJsonValue(baseUtils.getSysPathCache(uploadEntity.getPathUrlk()).get(0).getPath() + Constant.slash + attachmentList.get(0).getPath());
                        }else{
                            baseJson.setJsonValue(baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_BASE_URL).get(0).getPath() + Constant.slash + attachmentList.get(0).getPath());
                        }
                    }else{
                        //非图片格式让其显示成功图标即可
                        baseJson.setJsonValue(baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_UPLOAD_SUCCESS).get(0).getPath());
                    }
                }else{
                    baseJson.setJsonValue(baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_UPLOAD_FAIL).get(0).getPath());
                }
            }else{
                baseJson.setJsonValue(baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_UPLOAD_FAIL).get(0).getPath());
                baseJson.setMessage("上传失败");
            }
            return BaseResult.success(baseJson);
        } catch (Exception e) {
            baseJson.setMessage("上传失败、失败原因:"+e.getMessage());
            baseJson.setJsonID("0");
            return BaseResult.fail(baseJson);
        }
    }

    /**
     * 批量上传
     * @param map 校验类型
     * @return
     */
    @ApiOperation(value="批量上传文件", notes="批量上传文件")
    @PostMapping(value="/batch/upload")
    @Auth(value = "/batch/upload",authenticationType = Auth.AuthorizationType.NOT_REQUIRED_LOGIN)
    public BaseResult<BaseJson> uploadBatch(@RequestParam Map<String, Object> map, @RequestParam("mutilJehcFile") MultipartFile[] multfiles){
        List<BaseJson> baseJsonList = new ArrayList<>();
        List<MultipartFile> multipartFileList = new ArrayList<>(Arrays.asList(multfiles));
        /*CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        //先判断request中是否包涵multipart类型的数据，
        if (multipartResolver.isMultipart(request)) {
            //再将request中的数据转化成multipart类型的数据
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;
            Iterator iter = multiRequest.getFileNames();
            while(iter.hasNext()){
                MultipartFile file = multiRequest.getFile((String) iter.next());
                if(file != null){
                    multipartFileList.add(file);
                }
            }
        }*/

        UploadEntity uploadEntity = JsonUtil.fromFastJson(map, UploadEntity.class);
        try {
            //默认绝对路径
            String path = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_DEFAULT_PATH).get(0).getPath();
            //相对路径
            String relativePath = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_DEFAULT_RELATIVE_PATH).get(0).getPath();
            //校验xt_path_absolutek
            if(!StringUtils.isEmpty(uploadEntity.getPathAbsolutek())){
                if(!StringUtils.isEmpty(baseUtils.getSysPathCache(uploadEntity.getPathAbsolutek()).get(0).getPath())){
                    path = baseUtils.getSysPathCache(uploadEntity.getPathAbsolutek()).get(0).getPath();
                }
            }
            //校验xt_path_relativek
            if(!StringUtils.isEmpty(uploadEntity.getPathRelativek())){
                if(!StringUtils.isEmpty(baseUtils.getSysPathCache(uploadEntity.getPathRelativek()).get(0).getPath())){
                    relativePath = baseUtils.getSysPathCache(uploadEntity.getPathRelativek()).get(0).getPath();
                }
            }
            FileUtil.initPath(path);
            uploadEntity.setPathRelativek(relativePath);
            List<Attachment> attachmentList = fileService.upLoad(uploadEntity,multipartFileList,path);
            int i = attachmentService.addBatchAttachment(attachmentList);
            if(i>0){
                for(Attachment attachment : attachmentList){
                    BaseJson baseJson = new BaseJson();
                    baseJson.setJsonID(attachment.getId());
                    baseJson.setMessage("上传成功");
                    baseJson.setObject(attachment);
                    baseJson.setFileType(attachment.getType());
                    if(StringUtil.isNotEmpty(attachment.getType())){
                        if("image/jpeg".equals(attachment.getType())||
                                "image/png".equals(attachment.getType())||
                                "image/gif".equals(attachment.getType())||
                                "image/bmp".equals(attachment.getType())){
                            //校验是否为自定义路径
                            if(!StringUtils.isEmpty(uploadEntity.getPathUrlk())){
                                baseJson.setJsonValue(baseUtils.getSysPathCache(uploadEntity.getPathUrlk()).get(0).getPath()+ Constant.slash + attachment.getPath());
                            }else{

                                baseJson.setJsonValue(baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_BASE_URL).get(0).getPath()+ Constant.slash + attachment.getPath());
                            }
                        }else{
                            //非图片格式让其显示成功图标即可
                            baseJson.setJsonValue(baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_UPLOAD_SUCCESS).get(0).getPath());
                        }
                    }else{
                        baseJson.setJsonValue(baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_UPLOAD_FAIL).get(0).getPath());
                    }
                    baseJsonList.add(baseJson);
                }

            }else{
                BaseResult.fail("上传失败");
            }
            return BaseResult.success(baseJsonList);
        } catch (Exception e) {
            return BaseResult.fail("上传失败、失败原因:"+e.getMessage());
        }
    }

    /**
     * 按条件获取附件所有相关字段信息 并且与相关附件字段匹配
     * @param attachmentEntity
     * field_name与attachmentId必须满足的规则是如parameter={fieldName:'field1,field2,field3',attachmentId:'1,2,3'}一一对应
     */
    @ApiOperation(value="查询文件", notes="查询文件")
    @PostMapping(value="/attAchmentPathpp")
    @Auth(value = "/attAchmentPathpp",authenticationType = Auth.AuthorizationType.NOT_REQUIRED_LOGIN)
    public BaseResult<List<Map<String,Object>>> getAttachmentPathPP(@RequestBody AttachmentEntity attachmentEntity){

        Map<String, Object> condition = new HashMap<String, Object>();

        List<PathEntity> pathEntities = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_BASE_URL);

        if(null == pathEntities || pathEntities.isEmpty()){
            throw new ExceptionUtil("未能获取到路径");
        }

        PathEntity pathEntity = pathEntities.get(0);
        String path = pathEntity.getPath();

        List<Map<String,Object>> mapList = new ArrayList<>();
        if(!StringUtil.isEmpty(attachmentEntity.getId()) && !StringUtil.isEmpty(attachmentEntity.getFieldName())){

            if(attachmentEntity.getId().split(",").length>0){

                String[] idArray= attachmentEntity.getId().split(",");

                condition.put("id", attachmentEntity.getId().split(","));

                if(null != idArray){
                    for(int i = 0; i < idArray.length; i++){
                        Attachment attachment = attachmentService.getAttachmentById(idArray[i]);
                        //判断该附件是否使用自定义xt_path_urlk
                        if(null != attachment && !StringUtils.isEmpty(attachment.getPathUrlk())){
                            path = baseUtils.getSysPathCache(attachment.getPathUrlk()).get(0).getPath();
                        }
                        if(null != attachment){
                            Map<String, Object> model = new HashMap<String, Object>();
                            model.put("id", attachment.getId());
                            model.put("fileType", attachment.getType());
                            model.put("createTime", attachment.getCreateTime());
                            model.put("size", attachment.getSize());
                            //附件字段名称（即表单中附件字段）
                            model.put("fieldName", attachmentEntity.getFieldName().split(",")[i]);
                            if("image/jpeg".equals(attachment.getType())||
                                    "image/png".equals(attachment.getType())||
                                    "image/gif".equals(attachment.getType())||
                                    "image/bmp".equals(attachment.getType())){
                                model.put("path", path+ attachment.getPath());
                            }else{
                                //非图片格式让其显示成功图标即可
                                model.put("path", baseUtils.getSysPathCache("jehc_upload_sucess").get(0).getPath());
                            }
                            //整个路径如http://www.jehc.com/images/img.png
                            model.put("path", path+ attachment.getPath());
                            model.put("delFlag", attachment.getDelFlag());
                            model.put("name", attachment.getName());
                            model.put("createId", attachment.getCreateId());
                            model.put("modulesId", attachment.getModulesId());
                            model.put("modulesOrder", attachment.getModulesOrder());
                            model.put("title", attachment.getTitle());
                            mapList.add(model);
                        }
                    }
                    return BaseResult.success(mapList);
                }else{
                    return BaseResult.success();
                }
            }else{
                return BaseResult.success();
            }
        }else{
            return BaseResult.success();
        }
    }

    /**
     * 按条件获取附件所有相关字段信息 并且与相关附件字段匹配
     * @param attachmentEntity
     * field_name与attachmentId必须满足的规则是如parameter={fieldName:'field1,field2,field3',attachmentId:'1,2,3'}一一对应
     */
    @ApiOperation(value="查询文件", notes="查询文件")
    @PostMapping(value="/batch/attAchmentPathpp")
    @Auth(value = "/batch/attAchmentPathpp",authenticationType = Auth.AuthorizationType.NOT_REQUIRED_LOGIN)
    public BaseResult<List<Attachment>> getBatchAttachmentPathPP(@RequestBody AttachmentEntity attachmentEntity){

        Map<String, Object> condition = new HashMap<String, Object>();

        List<PathEntity> pathEntities = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_BASE_URL);

        if(null == pathEntities || pathEntities.isEmpty()){
            throw new ExceptionUtil("未能获取到路径");
        }

        PathEntity pathEntity = pathEntities.get(0);

        String path = pathEntity.getPath();

        List<Attachment> attachmentList = new ArrayList<>();

        if(!StringUtil.isEmpty(attachmentEntity.getId())){

            condition.put("id", attachmentEntity.getId().split(","));

            attachmentList = attachmentService.getAttachmentList(condition);

            for(Attachment attachment :attachmentList){
                //判断该附件是否使用自定义xt_path_urlk
                if(!StringUtils.isEmpty(attachment.getPathUrlk())){
                    path = baseUtils.getSysPathCache(attachment.getPathUrlk()).get(0).getPath();
                }
                /*if(null != xtAttachment){
                    if("image/jpeg".equals(xtAttachment.getXt_attachmentType())||
                            "image/png".equals(xtAttachment.getXt_attachmentType())||
                            "image/gif".equals(xtAttachment.getXt_attachmentType())||
                            "image/bmp".equals(xtAttachment.getXt_attachmentType())){
                    }else{
                        //非图片格式让其显示成功图标即可
                        xtAttachment.setXt_attachmentPath(baseUtils.getSysPathCache("jehc_upload_sucess").get(0).getXt_path());
                    }
                }*/
                //相对路径
                //String relativePath = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_DEFAULT_RELATIVE_PATH).get(0).getPath();
                //整个路径如http://www.jehc.com/images/img.png
                attachment.setFullUrl( path+ attachment.getPath());
            }
        }
        return BaseResult.success(attachmentList);
    }

    /**
     * 按条件获取附件所有相关字段信息
     * @param id
     */
    @ApiOperation(value="根据附件编号查询文件", notes="根据附件编号查询文件")
    @GetMapping(value="/file/attachment/{id}")
    @Auth(value = "/file/attachment/get",authenticationType = Auth.AuthorizationType.NOT_REQUIRED_LOGIN)
    public BaseResult<Attachment> getAttachmentPath(@PathVariable("id")String id){
        Attachment attachment = attachmentService.getAttachmentById(id);
        List<PathEntity> pathEntities = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_BASE_URL);
        if(null == pathEntities || pathEntities.isEmpty()){
            throw new ExceptionUtil("未能获取到路径");
        }
        PathEntity pathEntity = pathEntities.get(0);
        String path = pathEntity.getPath();
        //判断该附件是否使用自定义xt_path_urlk
        if(!StringUtils.isEmpty(attachment.getPathUrlk())){
            path = baseUtils.getSysPathCache(attachment.getPathUrlk()).get(0).getPath();
        }
                /*if(null != xtAttachment){
                    if("image/jpeg".equals(xtAttachment.getXt_attachmentType())||
                            "image/png".equals(xtAttachment.getXt_attachmentType())||
                            "image/gif".equals(xtAttachment.getXt_attachmentType())||
                            "image/bmp".equals(xtAttachment.getXt_attachmentType())){
                    }else{
                        //非图片格式让其显示成功图标即可
                        xtAttachment.setXt_attachmentPath(baseUtils.getSysPathCache("jehc_upload_sucess").get(0).getXt_path());
                    }
                }*/
        //相对路径
        //String relativePath = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_DEFAULT_RELATIVE_PATH).get(0).getPath();
        //整个路径如http://www.jehc.com/images/img.png
        attachment.setFullUrl( path+ attachment.getPath());
        return BaseResult.success(attachment);
    }

    /**
     * 下载文件
     * @return
     * @throws IOException
     */
    @ApiOperation(value="下载文件", notes="下载文件")
    @GetMapping(value="/downFile")
    @Auth(value = "/downFile",authenticationType = Auth.AuthorizationType.NOT_REQUIRED_LOGIN)
    public void downFile(HttpServletRequest request,HttpServletResponse response) throws IOException{
        String id = request.getParameter("id");
        if(!StringUtils.isEmpty(id)){
            Attachment attachment = attachmentService.getAttachmentById(id);
            String path = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_DEFAULT_PATH).get(0).getPath();/////////////////////后期全部废除Ehcache
            //判断该附件是否使用自定义xt_path_absolutek（自定义绝对路径K）
            if(null != attachment && !StringUtils.isEmpty(attachment.getPathAbsolutek())){
                path = baseUtils.getSysPathCache(attachment.getPathAbsolutek()).get(0).getPath();
            }
            // * 表示允许任何域名跨域访问
            response.setContentType("text/html;charset=utf-8");
            File file = new File(path+ Constant.slash + attachment.getName());
            String title = attachment.getTitle();
            if(!file.exists()){
                response.getWriter().println("<script type='text/javascript'>top.window.parent.toastrBoot(4,'<font color=red>您访问的文件已经不存在，请联系管理员！</font>');</script>");
            }else{
                int len=0;
                byte []buffers = new byte[1024];
                BufferedInputStream br = null;
                OutputStream ut = null;
                response.reset();
                response.setHeader("Access-Control-Allow-Origin", "*");
                response.setContentType("application/x-msdownload");
                response.setHeader("Content-Disposition","attachment;filename=" +java.net.URLEncoder.encode(title,"UTF-8"));
                br = new BufferedInputStream(new FileInputStream(file));
                ut = response.getOutputStream();
                while((len=br.read(buffers))!=-1){
                    ut.write(buffers, 0, len);
                }
                ut.flush();
                ut.close();
                br.close();
            }
        }else{
            response.getWriter().println("<script type='text/javascript'>top.window.parent.toastrBoot(4,'<font color=red>您访问的文件已经不存在，请联系管理员！</font>');</script>");
        }
    }

//    /**
//     * 下载文件（网络批量）
//     * @return
//     * @throws IOException
//     */
//	@RequestMapping(value="/downBatchFileByUrl")
//	public void downBatchFileByUrl(String[] pathList,HttpServletRequest request,HttpServletResponse response) throws IOException{
//		String downloadFilename = "jEHC开源平台压缩文件.zip";//文件的名称
//		downloadFilename = URLEncoder.encode(downloadFilename, "UTF-8");//转换中文否则可能会产生乱码
//		response.setContentType("application/octet-stream");// 指明response的返回对象是文件流
//        response.setHeader("Content-Disposition", "attachment;filename=" + downloadFilename);// 设置在下载框默认显示的文件名
//        ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
//        for (int i=0;i<pathList.length;i++) {
//           URL url = new URL(pathList[i]);
//           zos.putNextEntry(new ZipEntry(pathList[i]));
//           InputStream fis = url.openConnection().getInputStream();
//           bytesources[] buffer = new bytesources[1024];
//           int r = 0;
//           while ((r = fis.read(buffer)) != -1) {
//               zos.write(buffer, 0, r);
//           }
//           fis.close();
//          }
//        zos.flush();
//        zos.close();
//	}

    /**
     * 下载文件（非网络批量）
     * @return
     * @throws IOException
     */
    @ApiOperation(value="批量下载文件", notes="批量下载文件")
    @GetMapping(value="/downBatchFile")
    @Auth(value = "/downBatchFile",authenticationType = Auth.AuthorizationType.NOT_REQUIRED_LOGIN)
    public void downBatchFile(HttpServletRequest request,HttpServletResponse response) throws IOException{
        String id = request.getParameter("id");
        if(!StringUtils.isEmpty(id)){
            String[] ids = id.split(",");
            List<String> paths = new ArrayList<String>();
            List<String> oldNames = new ArrayList<String>();
            for(String id_:ids){
                String path = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_DEFAULT_PATH).get(0).getPath();
                Attachment attachment = attachmentService.getAttachmentById(id_);
                //判断该附件是否使用自定义xt_path_absolutek（自定义绝对路径K）
                if(null != attachment && !StringUtils.isEmpty(attachment.getPathAbsolutek())){
                    path = baseUtils.getSysPathCache(attachment.getPathAbsolutek()).get(0).getPath();

                }
                /*if(path.substring(path.length()-2, path.length()-1).equals("/")){
                    path = path+xtAttachment.getXt_attachmentName();
                }else {

                }*/
                path = path+ Constant.slash + attachment.getName();
                oldNames.add(attachment.getTitle());
                paths.add(path);
            }
            FileUtil fileUtil = new FileUtil();
            FileEntity fileEntity = new FileEntity(paths,oldNames,"D://","jEhc开源.zip");
            fileUtil.callZipFilePath(fileEntity);
        }else{
            response.getWriter().println("<script type='text/javascript'>top.window.parent.toastrBoot(4,'<font color=red>您访问的文件已经不存在，请联系管理员！</font>');</script>");
        }
    }

    /**
     * 附件预览
     * @param multipartFile
     * @param response
     */
    @ApiOperation(value="附件预览", notes="附件预览")
    @RequestMapping(value = "/preview")
    @Auth(value = "/preview",authenticationType = Auth.AuthorizationType.NOT_REQUIRED_LOGIN)
    public void preview(@RequestParam("file")MultipartFile multipartFile, HttpServletResponse response) {
        officeUtil.preview(multipartFile,response);
    }

    /**
     * 附件预览
     * @param id
     * @param response
     */
    @ApiOperation(value="附件预览", notes="附件预览")
    @GetMapping(value="/preview/{id}")
    @Auth(authenticationType = Auth.AuthorizationType.NOT_REQUIRED_LOGIN)
    public void preview(@PathVariable("id")String id,HttpServletResponse response){

        Attachment attachment = attachmentService.getAttachmentById(id);

        String path = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_DEFAULT_PATH).get(0).getPath();/////////////////////后期全部废除Ehcache

        //判断该附件是否使用自定义xt_path_absolutek（自定义绝对路径K）
        if(null != attachment && !StringUtils.isEmpty(attachment.getPathAbsolutek())){

            path = baseUtils.getSysPathCache(attachment.getPathAbsolutek()).get(0).getPath();

        }

        try {

            FileInputStream  fileInputStream = new FileInputStream(path+ Constant.slash + attachment.getName());

            officeUtil.preview(fileInputStream, attachment.getTitle(),response);

        }catch (Exception e){
            log.error("预览异常：{}",e);
        }
    }
}
